﻿using System;
using System.Configuration;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;


namespace PRV_BO.Domain
{
	public class PotreroBO : IEditableObject, INotifyPropertyChanged, IDataErrorInfo 
		{
			private bool m_Editing;
			private string NombrePotreroOld;
			private string DiasReposoOld;
			internal PotrerosCollection m_Parent;
			private string _nombrePotrero;
			private string _diasReposo;

			#region Public properties

			[Browsable(false)]
			public bool IsNew { get; set; }

			public string NombrePotrero 
			{ 
				get { return _nombrePotrero; } 

				set 
				 { 

					bool bPot = false;
					if (this.m_Parent != null && _nombrePotrero != string.Empty)
					{
						bPot = this.m_Parent.Any(p => p.NombrePotrero == value);
					}
					if (bPot)
					{
						m_PropErrors["NombrePotrero"] = "Nombre de potrero ya existe";
						m_Error = "";
						this.CancelEdit();
					}
					else
					{
						if (_nombrePotrero != value)
						{
							_nombrePotrero = value;
						}
						m_PropErrors["NombrePotrero"] = string.Empty;
						m_Error = string.Empty;
						FirePropertyChangedNotification("NombrePotrero");
					}
					}
			}

			public string Area { get; set; }

			public  string DiasReposo 
			{
			  get {
					  return _diasReposo; 
				  }
			  set { 
				   _diasReposo = value;
				   FirePropertyChangedNotification("DiasReposo");
			  }
			}

			string _diasOcupado = string.Empty;
		   
			public string DiasOcupado
			{
				get
				{
					return _diasOcupado;
				}
				set
				{
					_diasOcupado = value;
					FirePropertyChangedNotification("DiasOcupado");
				}
			}

			string _loteOcupado;

			public string LoteOcupado
			{
				get
				{
					return _loteOcupado;
				}
			}

			public DateTime FechaUltimaEntrada
			{
				get
				{
					if (Rotaciones.Count == 0)
					{
						return DateTime.Parse("1900-01-01");
					}
					else
					{

						DateTime? dt = Rotaciones.Max(R => R.FechaEntrada);
						return ((DateTime)dt).Date;
					}
				}
			}

			public DateTime FechaUltimaSalida
			{
				get
				{
					if (Rotaciones.Count == 0)
					{
						return DateTime.Parse("1900-01-01");
					}
					else
					{
						DateTime? dt = Rotaciones.Max(R => R.FechaSalida);
						return ((DateTime)dt).Date;
					}
				}
			}

			private bool _estaocupado;

			[Browsable(false)]
			public bool Ocupado
			{
				get { return _estaocupado; }
			}
			#endregion

			#region constructor
			public PotreroBO()
			{
				NombrePotrero = string.Empty;
				Area = string.Empty;
				IsNew = true;
			}
			
			public PotreroBO(PotrerosCollection PC)
			{
				m_Parent = PC;
			}

			public PotreroBO(PotrerosCollection PC, string nombrePotrero, string area)
			{
				m_Parent = PC;
				NombrePotrero = nombrePotrero;
				Area = area;
				Rotaciones = PresenterPRV.GetRotaciones(NombrePotrero);
			}


			public PotreroBO(string nombrePotrero, string area)
			{
				NombrePotrero = nombrePotrero;
				Area = area;
				Rotaciones = PresenterPRV.GetRotaciones(NombrePotrero);
			}

			#endregion

			static string GetConnectionStringByName(string name)
			{
				// Assume failure.
				string returnValue = null;

				// Look for the name in the connectionStrings section.
				ConnectionStringSettings settings = ConfigurationManager.ConnectionStrings[name];

				// If found, return the connection string.
				if (settings != null)
					returnValue = settings.ConnectionString;

				return returnValue;
			}

			private void FirePropertyChangedNotification(string propName)
			{
				if (PropertyChanged != null)
				{
					PropertyChanged(this,new PropertyChangedEventArgs(propName));
				}
			}

			private RotacionesCollection _Rotaciones = new RotacionesCollection();


			public RotacionesCollection Rotaciones
			{
				get { return _Rotaciones; }

				set 
				{ 
					  _Rotaciones = value;
					  _estaocupado = false;
					  if (_Rotaciones.Count == 0)
					  {
						  _diasReposo = "--";
						  return;
					  }
					  TimeSpan DR;
					  RotacionBO rbo = _Rotaciones.FirstOrDefault(R => R.FechaSalida == DateTime.Parse("1900-01-01"));
					  if (rbo != null)
					  {
						  DateTime? dt = rbo.FechaEntrada;
						  DR = (TimeSpan) (DateTime.Now - dt);
						  _diasOcupado = DR.Days.ToString();
						  _diasReposo = "--";
						  _estaocupado = true;
						  _loteOcupado = rbo.Lote;
					  }
					  else
					  {
						  DateTime? dt = _Rotaciones.Max(S => S.FechaSalida);
						  DR = (TimeSpan)(DateTime.Now - dt);
						  _diasReposo = DR.Days.ToString();
					  }
				}
			}

			#region IDataErrorInfo Members

			private string m_Error = string.Empty;
			private Hashtable m_PropErrors = new Hashtable();

			[Browsable(false)]
			public string Error
			{
				get { return m_Error; }
			}

			[Browsable(false)]
			public string this[string columnName]
			{
				get 
				{ return (string)m_PropErrors[columnName]; }
			}

			#endregion

			#region IEditableObject Members

			public void BeginEdit()
			{
				if (!m_Editing)
				{
					NombrePotreroOld = NombrePotrero;
					DiasReposoOld = DiasReposo;
				}

				m_Editing = true;
			}

			public void CancelEdit()
			{
				if (m_Editing)
				{
					_nombrePotrero = NombrePotreroOld ;
					DiasReposo = DiasReposoOld;
				}

				m_Editing = false;
			}

			public void EndEdit()
			{
				m_Editing = false;
			}

			#endregion

			#region INotifyPropertyChanged Members

			public event PropertyChangedEventHandler PropertyChanged;

			#endregion

			public override string ToString()
			{
				return this.NombrePotrero;
			}

		}

	public class ComentarioBO
	{
		[Browsable(false)]
		public Int32 ID { get; set; }
		[Browsable(false)]
		public bool IsNew { get; set; }
		public string   NombrePotrero { get; set; }
		public DateTime Fecha { get; set; }
		public string   Comentario { get; set; }

		#region Constructors

		public ComentarioBO(Int32 idc,  string nombrePotrero,DateTime fecha, string texto)
		{
			this.ID = idc; 
			this.NombrePotrero = nombrePotrero;
			this.Fecha = fecha;
			this.Comentario = texto;
		}

		#endregion

	}

	public class ComentariosCollection : SortableBindingList<ComentarioBO>
	{
		public ComentariosCollection() : base() { }
		public ComentariosCollection(IList<ComentarioBO> ic) : base(ic) { }

	}

	public class PotrerosCollection : SortableBindingList<PotreroBO>
	{
		public PotrerosCollection() : base() 
		{
		}
		public PotrerosCollection(IList<PotreroBO> ic) : base(ic) { }
	}

	public class Areas : SortableBindingList<String>
	{
		public Areas(IList<String> ic) : base(ic) { }
	}

	public class SortableBindingList<T> : BindingList<T>
	{
		#region Fields

		private PropertyDescriptor propertyDescriptor;
		private ListSortDirection listSortDirection;
		private bool isSorted;

		#endregion

		#region Constructors

		/// <summary>
		/// Default constructor
		/// </summary>
		public SortableBindingList()
		{
			isSorted = true;
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="enumerable"></param>
		public SortableBindingList(IEnumerable<T> enumerable)
		{
			if (enumerable == null)
			{
				throw new ArgumentNullException("enumerable");
			}

			foreach (T t in enumerable)
			{
				this.Add(t);
			}
		}

		#endregion

		#region Overriden Methods

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.SupportsSortingCore"/>
		/// </summary>
		protected override bool SupportsSortingCore
		{
			get { return true; }
		}

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.IsSortedCore"/>
		/// </summary>
		protected override bool IsSortedCore
		{
			get { return this.isSorted; }
		}

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.SortPropertyCore"/>
		/// </summary>
		protected override PropertyDescriptor SortPropertyCore
		{
			get { return this.propertyDescriptor; }
		}

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.SortDirectionCore"/>
		/// </summary>
		protected override ListSortDirection SortDirectionCore
		{
			get { return this.listSortDirection; }
		}

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.ApplySortCore"/>
		/// </summary>
		protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
		{
			List<T> itemsList = this.Items as List<T>;
			itemsList.Sort(delegate(T t1, T t2)
			{
				this.propertyDescriptor = prop;
				this.listSortDirection = direction;
				this.isSorted = true;

				int reverse = direction == ListSortDirection.Ascending ? 1 : -1;

				object value1 = prop.GetValue(t1);
				object value2 = prop.GetValue(t2);

				return reverse * Comparer.Default.Compare(value1, value2);
			});

			this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
		}

		/// <summary>
		/// <see cref="BindingList&lt;T&gt;.RemoveSortCore"/>
		/// </summary>
		protected override void RemoveSortCore()
		{
			this.isSorted = false;
			this.propertyDescriptor = base.SortPropertyCore;
			this.listSortDirection = base.SortDirectionCore;
		}

		#endregion
	}

	}


